import React, {
  Ref,
  useImperativeHandle,
  useEffect,
  useMemo,
  useState,
  useCallback,
  useRef,
} from 'react';
import api from './api';
import { useEvents, multilingualFormat } from '@inbiz/utils';
import { Radio, Checkbox, Space, Select, Empty } from 'antd';
import './index.less';
import { toJS } from '@formily/reactive';
import { TextWidget, getMessage } from '@inbiz/react';
import { observer } from '@formily/react';
import { GlobalRegistry } from '@inbiz/core';
import {
  IBaseEformStaticList,
  defaultValueFormat,
  useRequestData,
  originValueFormat,
} from '../public';
// import { getSaveValue } from 'packages/components/EformMemberSelect/preview/wap/util';
const { Option } = Select;
type IRef = Ref<ReturnType<typeof api>>;

export type EformStaticListProps = IBaseEformStaticList & {
  defaultValue:any;
  viewMode?: string;
  emit?: {
    (type: 'onChange', arg: string[] | string | null): void;
    (type: 'onLoad'): void;
    (type: 'onSuccess', arg: object[]): void;
    (type: 'onError'): void;
    (type: 'onDropdownVisibleChange', arg: boolean): void;
    (type: 'onClick', e: React.MouseEvent<HTMLElement, MouseEvent>, item: object): void;
  };
  ref: IRef
};

const EformStaticList: EFC<EformStaticListProps, any> = observer(
  (props: EformStaticListProps) => {
    const ref = props.ref;
    const { disabledOptions, dataGroupId } = props;
    const { appId } = useMemo(() => {
      return {
        appId: props.inbiz?.appInfo?.appId,
      };
    }, []);
    const [configEvents] = useEvents(props.callBackEvents, props.emit);
    const { data, mutate: $options, runAsync } = useRequestData(props, configEvents);
    const options = useMemo(() => {
      if (data) {
        return data.map(item => ({ ...item, label: multilingualFormat(item.label) }))
      } else {
        return []
      }
    }, [data, GlobalRegistry.getDesignerLanguage()]);

    // option获取成功
    const getOptionsed = useRef<boolean>(false);
    // 是否清空
    const isClear = useRef<boolean>(false);
    // 选中的值
    const [selectValue, $selectValue] = useState<string[] | string | number | number[] | null>(
      null,
    );
    // 上一次value
    const before = useRef<any>(null);
    // 下拉组件
    const selectRef = useRef<any>();

    useImperativeHandle(
      ref,
      () => ({
        ...api(configEvents, selectValue, options, setOptions, props, options, $selectValue),
      }),
      [selectValue, options],
    );

    // 请求数据源
    const getData = useCallback(
      (params: object, isFirst = false) => {
        return runAsync({ appId, ...(params || {}) }).then(
          (res) => {
            const initValue = Array.isArray(props.value) ? props.value[0] : props.value;
            if (res?.[0]?.value && (initValue || initValue === 0)) {
              const typeofStr = typeof res[0].value;
              if (typeofStr != typeof initValue) {
                //@ts-ignore
                $selectValue((value) => {
                  if (value === undefined) {
                    return undefined;
                  }
                  if (Array.isArray(value)) {
                    return value.map((item) =>
                      typeofStr === 'string' ? item?.toString() : Number(item),
                    );
                  } else {
                    return typeofStr === 'string' ? value?.toString() : Number(value);
                  }
                });
              }
            }
            getOptionsed.current = true;
            props.emit?.('onSuccess', res as []);
            if (isFirst) {
              props.emit?.('onLoad');
            }
          },
          (e) => {
            props.emit?.('onError');
          },
        );
      },
      [runAsync, props.dataGroupId, props.emit],
    );

    useEffect(() => {
      if (!(props.autoLoading == undefined || props.autoLoading) || (!props.dataGroupId && !configEvents.current.onRequest)) {
        if (!getOptionsed.current) {
          props.emit?.('onLoad');
        }
        return;
      }
      if (typeof props.dataGroupId == 'object') {
        const modelKey = props.dataGroupId['modelKey'];
        if (modelKey) {
          getData({ key: modelKey }, true);
        } else {
          getData({}, true);
        }
      } else {
        getData({ groupKey: props.dataGroupId }, true);
      }
    }, [typeof props.dataGroupId === 'string' ? props.dataGroupId : JSON.stringify(props.dataGroupId || {}), props.autoLoading]);

    // 初始化默认值
    useEffect(() => {
      props.selectMode ? $selectValue([]) : $selectValue(null);
    }, [props.selectMode]);

    // 发起初始值过滤处理
    useEffect(() => {
      if (getOptionsed.current) {
        let value = toJS(props.value) || props.defaultValue;
        if (String(value) !== String(before.current) && !isClear?.current) {
          if (typeof value === 'string') {
            value = value.split(',');
            value = value.map((item: string) => item.trim());
          }
          if (props.value === 0) {
            value = props.value;
          }
          if (!Array.isArray(value)) {
            value = [value];
          }
          initCheckValue(value);
          isClear.current = false;
        }
      }
    }, [options, props.selectMode, props.defaultValue]);

    useEffect(() => {
      $selectValue(props.value);
    }, [props.value]);
    // 初始值过滤处理
    const initCheckValue = useCallback(
      (value) => {
        value = value ? value : [];
        let arr: any = [];
        value.map((item: any) => {
          let fil = options.filter((val: any) => val.value === item);
          fil.length && arr.push(fil[0].value);
        });
        arr = [...new Set(arr)];
        if (props.selectMode) {
          before.current = arr;
          $selectValue(arr);
        } else {
          before.current = arr.length ? arr[0] : null;
          $selectValue(arr.length ? arr[0] : null);
        }
      },
      [options, props.selectMode],
    );

    // 扩展代码loadData设置options
    const setOptions = useCallback(
      (list: any[]) => {
        $options(list);
      },
      [props.selectMode],
    );

    // 单选组值改变
    const redioChange = useCallback(
      (e) => {
        props.onChange?.(e.target.value);
      },
      [props.onChange],
    );

    // 多选、下拉选择值改变
    const selectChange = useCallback(
      (e) => {
        if (e || e === 0) {
          props.onChange?.(e);
        }
      },
      [props.onChange],
    );

    // 单选选择后使组件失去焦点
    const onSelect = useCallback(() => {
      if (!props.selectMode) {
        selectRef.current?.blur();
      }
    }, [props.selectMode]);
        // 查看模式
 
    const [text, $text] = useState('');
    useEffect(() => {
      $text(ref?.current?.getText?.() || '')
    }, [selectValue, options])
    // 单选平铺小组件
    const EformRadio = useMemo(() => {
      let newOptions = props.hideDisabledOptions
        ? options.filter((item: any) => disabledOptions?.indexOf(item.value) === -1)
        : options;

      return <Radio.Group
      value={selectValue}
      disabled={props.readOnly || props.disabled}
      onChange={redioChange}
    >
      <Space
        direction={props.layoutMode === 'portrait' ? 'vertical' : 'horizontal'}
        align="start"
      >
        {newOptions.map((item) => {
          return (
            <Radio
              value={item.value}
              key={item.value}
              onClick={(e) => props.emit?.('onClick', e, item)}
              disabled={
                item.disabled ?? disabledOptions
                  ? disabledOptions?.indexOf(item.value?.toString?.()) != -1
                    ? true
                    : false
                  : false
              }
            >
              <TextWidget>{item.label}</TextWidget>
            </Radio>
          );
        })}
      </Space>
    </Radio.Group>;
    }, [
      options,
      props.layoutMode,
      props.readOnly,
      props.disabled,
      selectValue,
      disabledOptions,
      props.hideDisabledOptions,
    ]);



    // 多选平铺小组件
    const EformCheckBox = useMemo(() => {
      let newOptions = props.hideDisabledOptions
        ? options.filter((item: any) => disabledOptions?.indexOf(item.value) === -1)
        : options;
      const dValue = Array.isArray(selectValue) ? selectValue : [selectValue];
      return <Checkbox.Group
      disabled={props.readOnly || props.disabled}
      onChange={selectChange}
      value={dValue}
    >
      <Space
        direction={props.layoutMode === 'portrait' ? 'vertical' : 'horizontal'}
        align="start"
      >
        {newOptions.map((item) => {
          return (
            <Checkbox
              value={item.value}
              key={item.value}
              onClick={(e) => props.emit?.('onClick', e, item)}
              disabled={
                item.disabled ?? disabledOptions
                  ? disabledOptions?.indexOf(item.value?.toString?.()) != -1
                    ? true
                    : false
                  : false
              }
            >
              <TextWidget>{item.label}</TextWidget>
            </Checkbox>
          );
        })}
      </Space>
    </Checkbox.Group>;
    }, [
      options,
      props.layoutMode,
      props.readOnly,
      props.disabled,
      selectValue,
      disabledOptions,
      props.hideDisabledOptions,
    ]);

    // 下拉小组件
    const EformSelect = useMemo(() => {
      let newOptions = props.hideDisabledOptions
        ? options.filter((item: any) => disabledOptions?.indexOf(item.value) === -1)
        : options;
      // 在子表格中，数据接口回来时才展示
      if (!options.length && props.componentIsInline) {
        return null;
      }

      return <Select
      value={selectValue}
      placeholder={<TextWidget>{props.placeholder}</TextWidget>}
      disabled={props.readOnly || props.disabled}
      style={{ width: '100%' }}
      showArrow
      showSearch
      ref={selectRef}
      allowClear={!props.selectMode}
      filterOption={(val, opt: any) => {
        let label = (opt?.children?.props?.children as string) || '';
        let status = label?.toString().includes(val.trim());
        return status;
      }}
      dropdownClassName={'inbiz-eform-static-list-select-down'}
      dropdownStyle={{ minWidth: props.componentIsInline ? '360px' : 'unset' }}
      virtual={false}
      listHeight={props.selectHeight}
      onChange={selectChange}
      onSelect={onSelect}
      mode={props.selectMode ? 'multiple' : undefined}
      onDropdownVisibleChange={(e) => props.emit?.('onDropdownVisibleChange', e)}
      onClear={() => {
        isClear.current = true;
        $selectValue(null);
        props.onChange && props.onChange(null);
      }}
      notFoundContent={
        <Empty
          image={Empty.PRESENTED_IMAGE_SIMPLE}
          description={<TextWidget>EformStaticList.nodata</TextWidget>}
        />
      }
    >
      {newOptions.map((item) => {
        return (
          <Option
            value={item.value}
            key={item.value}
            title={getMessage(item.label || item.value)}
            disabled={
              item.disabled ?? disabledOptions
                ? disabledOptions?.indexOf(item.value?.toString()) != -1
                  ? true
                  : false
                : false
            }
          >
            <TextWidget>{item.label || item.value}</TextWidget>
          </Option>
        );
      })}
    </Select>;
    }, [
      options,
      props.selectMode,
      props.placeholder,
      props.readOnly,
      props.disabled,
      props.selectHeight,
      selectValue,
      disabledOptions,
      props.hideDisabledOptions,
      props.componentIsInline,
    ]);
    let dom: any
    if (props.viewMode === 'look') {
      dom =  text
    } else {
      dom = props.showMode === 2 ? EformSelect : props.selectMode ? EformCheckBox : EformRadio;
    }
    // const dom = props.showMode === 2 ? EformSelect : props.selectMode ? EformCheckBox : EformRadio;
    return <div className={'inbiz-eform-static-list-nav'}>{dom}</div>;
  },
  { forwardRef: true }
);

EformStaticList.displayName = 'EformStaticList';

EformStaticList.defaultValueFormat = defaultValueFormat;
EformStaticList.originValueFormat = originValueFormat;
export default EformStaticList;
